package com.dx.mes.service.brm.service;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import com.dx.common.table.ppt.*;
import com.dx.mes.common.dao.IRetBoxXfrDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.dx.mes.common.dao.IRetBoxDao;
import com.dx.mes.common.dao.IRetCrtNoDao;
import com.dx.mes.common.dao.IRetPrdInfoDao;
import com.dx.mes.common.transcoder.util.AppContext;
import com.dx.mes.common.transcoder.util.JacksonUtil;
import com.dx.mes.common.transcoder.util.LogUtils;
import com.dx.mes.common.transcoder.util.Util;
import com.dx.mes.facade.brm.service.IFbpboxmagService;
import com.dx.mes.facade.brm.tx.Fbpboxmag.FbpboxmagI;
import com.dx.mes.facade.brm.tx.Fbpboxmag.FbpboxmagIA;
import com.dx.mes.facade.brm.tx.Fbpboxmag.FbpboxmagO;
import com.dx.mes.facade.brm.tx.Fbpboxmag.FbpboxmagOA;

import static com.dx.mes.common.bean.def.GenericDef.*;

@Service("fbpboxmagService")
@SuppressWarnings({"unchecked"})
public class FbpboxmagService implements IFbpboxmagService{
	private static final String TX_NAME = T_FBPBOXMAG;
	private LogUtils logUtils;
	@Autowired
	private IRetBoxDao retBoxDao;
	@Autowired
	private IRetPrdInfoDao retPrdInfoDao;
	@Autowired
	private IRetCrtNoDao retCrtNoDao;
	@Autowired
	private IRetBoxXfrDao retBoxXfrDao;
	public String subMainProc(String evt_no,String strInMsg) {
		AppContext.clear();
		AppContext.setCurrServiceName(FbpboxmagService.class.getSimpleName());
		AppContext.setCurrEventNumber(evt_no);
		logUtils = new LogUtils(FbpboxmagService.class);
		logUtils.info("[InTrx:" + strInMsg + "]");
		
		String strOutTrx = null;
		FbpboxmagO outTrx = new FbpboxmagO();
		
		outTrx.setTrx_id(TX_NAME);
		outTrx.setType_id(TRX_OUT);
		outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));
		
		try {
			FbpboxmagI inTrx = new FbpboxmagI();
			inTrx = JacksonUtil.fromJson(strInMsg, FbpboxmagI.class);
			char action_flg = inTrx.getAction_flg().charAt(0);
			switch (action_flg) {
			case ACTION_FLG_ADD:
				outTrx = addFnc(inTrx);
				break;
			case ACTION_FLG_QUERY:
				outTrx = queryFnc(inTrx);
				break;
			case ACTION_FLG_DELETE:
				outTrx = deleteFnc(inTrx);
				break;
//				case ACTION_FLG_MOVEIN_QUERY:
//				outTrx = moveInQueryFnc(inTrx);
//				break;
			default:
				outTrx = errActionFnc();
			}
			if (RETURN_CODE_OK.equals(outTrx.getRtn_code())) {
				retBoxDao.flushCurSession();
			} else {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			}
		} catch (Exception ex) {
			outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
			outTrx.setRtn_mesg(ex.toString());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		} finally {
			strOutTrx = JacksonUtil.toJSONStr(outTrx);
			logUtils.info("[OutTrx:" + strOutTrx + "]");
		}
		return strOutTrx;
	}
	
	private void setBoxInfo(String box_id, FbpboxmagI inTrx, Timestamp current_timestamp){
		Ret_box ret_box = new Ret_box();
		ret_box.setBox_id(box_id);
		ret_box.setBox_size(inTrx.getBox_size());
		ret_box.setBox_cate(inTrx.getBox_cate());
		ret_box.setBox_set_code(inTrx.getBox_set_code());
		ret_box.setBox_own(BOX_OWN_CF);
		ret_box.setBox_stat(PROC_EMPTY);
		ret_box.setReal_emp(_YES);
		ret_box.setValid_flg(_YES);
		ret_box.setBox_clean_flg(_NO);
		ret_box.setBox_use_cnt(0);
		ret_box.setPrd_qty(0);
		ret_box.setChip_qty(0);
		ret_box.setBnk_flg(BANK_OUT);
		ret_box.setEvt_usr(inTrx.getEvt_usr());
		ret_box.setEvt_cate(EVT_BOX_BUILD);
		ret_box.setEvt_timestamp(current_timestamp);
		ret_box.setBox_rgst_timestamp(current_timestamp);
		ret_box.setPrd_admin_flg("NNNNNNNNNNNNNNNNNNNN");
		retBoxDao.save(ret_box);
	}
	public FbpboxmagO addFnc(FbpboxmagI inTrx) {
		FbpboxmagO outTrx = new FbpboxmagO();
		outTrx.setTrx_id(TX_NAME);
		outTrx.setType_id(TRX_OUT);
		
		Timestamp current_timestamp = Util.getCurrentTimestamp();
		List<FbpboxmagOA> oaryList = new ArrayList<FbpboxmagOA>();
		
		if( !inTrx.getBox_cate().trim().equals(PPBOX) ){
			Ret_box ret_box = retBoxDao.get(inTrx.getBox_id());
			if (ret_box != null) {
				outTrx.setRtn_code(E_FBPBOXMAG_BOX_ALREADY_EXIST + "");
				outTrx.setRtn_mesg("箱子[" + inTrx.getBox_id() + "]已经存在，请勿重复创建！！！");
				return outTrx;
			}
			setBoxInfo(inTrx.getBox_id(), inTrx, current_timestamp);

			//add ret_box xfr information
			Ret_box_xfr ret_box_xfr = retBoxXfrDao.get(inTrx.getBox_id());
			if(ret_box_xfr == null){
				ret_box_xfr = new Ret_box_xfr();
				ret_box_xfr.setBox_id_fk(inTrx.getBox_id());
				ret_box_xfr.setEvt_cate(EVT_BOX_BUILD);
				ret_box_xfr.setEvt_usr(inTrx.getEvt_usr());
				ret_box_xfr.setEvt_timestamp(current_timestamp);
				retBoxXfrDao.save(ret_box_xfr);
			}
			//set outTrx
			FbpboxmagOA oary = new FbpboxmagOA();
			oary.setBox_id(inTrx.getBox_id());
			oary.setBox_cate(inTrx.getBox_cate());
			oary.setBox_set_code(inTrx.getBox_set_code());
			oary.setBox_stat(PROC_EMPTY);
			oaryList.add(oary);
		}else{
			int i=0;
			String ppbox_key_id = createPpboxKeyID();
			String ppbox_id="";
			for(i=0;i<inTrx.getBox_cnt();i++){
				ppbox_id = createPpboxID(ppbox_key_id, inTrx, current_timestamp);
				setBoxInfo(ppbox_id, inTrx, current_timestamp);
				//set outTrx
				FbpboxmagOA oary = new FbpboxmagOA();
				oary.setBox_id(ppbox_id);
                oary.setBox_size(inTrx.getBox_size());
				oary.setBox_cate(inTrx.getBox_cate());
				oary.setBox_set_code(inTrx.getBox_set_code());
				oaryList.add(oary);
			}
		}
		outTrx.setOary(oaryList);
		outTrx.setTbl_cnt(oaryList.size());
		outTrx.setRtn_code(RETURN_CODE_OK);
		outTrx.setRtn_mesg(RETURN_MESG_OK);
		return outTrx;
	}
	/**
	 * create PPBOX ID
	 * @param ppbox_key_id
	 * @return
	 */
	private String createPpboxID(String ppbox_key_id, FbpboxmagI inTrx, Timestamp current_timestamp) {
		String ppbox_id="";
		Ret_crt_no ret_crt_no = new Ret_crt_no();
		Ret_crt_noId id = new Ret_crt_noId();
		id.setType(PPBOX_TYPE);
		id.setKey_id(ppbox_key_id);
		ret_crt_no = retCrtNoDao.get(id);
		if(ret_crt_no == null){
			Ret_crt_no ret_crt_no_new = new Ret_crt_no();
			ret_crt_no_new.setId(id);
			String serial_no = String.format("%03d", 1);
			ret_crt_no_new.setSerial_no(serial_no);
			ret_crt_no_new.setEvt_usr(inTrx.getEvt_usr());
			ret_crt_no_new.setEvt_timestamp(current_timestamp);
			ppbox_id = ppbox_key_id + "001";
			retCrtNoDao.save(ret_crt_no_new);
		}else{
			String old_serial_no = ret_crt_no.getSerial_no();
			int old_serial_no_int = Integer.valueOf(old_serial_no);
			int new_serial_no_int = old_serial_no_int + 1;
			String new_serial_no = String.format("%03d", new_serial_no_int);
			ret_crt_no.setSerial_no(new_serial_no);
			ret_crt_no.setEvt_usr(inTrx.getEvt_usr());
			ret_crt_no.setEvt_timestamp(current_timestamp);
			retCrtNoDao.update(ret_crt_no);
			ppbox_id = ppbox_key_id + new_serial_no;
		}
		return ppbox_id;
	}

	/**
	 * Create ppbox key id
	 * @return
	 */
	private String createPpboxKeyID(){
		Calendar c = Calendar.getInstance();
		int year = c.get(Calendar.YEAR);
		int m=c.get(Calendar.MONTH)+1;
		int d=c.get(Calendar.DATE);
		
		String str_year = String.valueOf(year).substring(2);
		String str_month=String.valueOf(m);
		if( m==10 ){
			str_month = "A";
		}else if( m==11 ){
			str_month = "B";
		}else if( m==12 ){
			str_month = "C";
		}
		String str_day = String.valueOf(d);
		String ppbox_key_id = str_year + str_month + str_day;
		
		return ppbox_key_id;
	}
	public FbpboxmagO queryFnc(FbpboxmagI inTrx) {
		FbpboxmagO outTrx = new FbpboxmagO();
		outTrx.setTrx_id(TX_NAME);
		outTrx.setType_id(TRX_OUT);
		
		String box_id = inTrx.getBox_id();
		String tool_id = inTrx.getTool_id_fk();
		String hql = "FROM Ret_box where 1=1 ";
		
		if (box_id != null) {
			hql = hql + " and id.box_id ='" + box_id + "'";
		}else if(tool_id != null){
			hql += "and tool_id_fk ='"+tool_id+"'";
		}else {
			if (inTrx.getBox_cate() != null) {
				hql = hql + " and box_cate ='" + inTrx.getBox_cate() + "'";
			}
			if (inTrx.getBox_set_code() != null) {
				hql = hql + " and box_set_code ='" + inTrx.getBox_set_code() + "'";
			}
			if (inTrx.getBox_size() != null) {
				hql = hql + " and box_size ='" + inTrx.getBox_size() + "'";
			}
		}
		if(inTrx.getBox_stat() != null){
			hql = hql + " and box_stat ='" + inTrx.getBox_stat() + "'";
		}
		hql = hql + " order by box_rgst_timestamp desc";
		List<Ret_box> retBoxList = retBoxDao.find(hql);

		if (retBoxList.isEmpty()) {
			outTrx.setRtn_code(E_RET_BOX + E_READ_NOT_FOUND + "");
			outTrx.setRtn_mesg("未找到箱号信息！");
			return outTrx;
		}
		List<FbpboxmagOA> oaryList = new ArrayList<FbpboxmagOA>();
		for (Ret_box retBox : retBoxList) {
			FbpboxmagOA oary = new FbpboxmagOA();
			oary.setBox_id(retBox.getBox_id());
			oary.setBox_stat(retBox.getBox_stat());
			oary.setPrd_qty(retBox.getPrd_qty());
			oary.setTool_id_fk(retBox.getTool_id_fk());
			oary.setWo_id_fk(retBox.getWo_id_fk());
			oary.setMdl_id_fk(retBox.getMdl_id_fk());
			oary.setCus_no(retBox.getCus_no());
			oary.setBox_cate(retBox.getBox_cate());
			oary.setBox_size(retBox.getBox_size());
			oary.setBox_set_code(retBox.getBox_set_code());
			oary.setReal_emp(retBox.getReal_emp());
			oaryList.add(oary);
		}
		outTrx.setOary(oaryList);
		outTrx.setTbl_cnt(oaryList.size());
		outTrx.setRtn_code(RETURN_CODE_OK);
		outTrx.setRtn_mesg(RETURN_MESG_OK);
		return outTrx;
	}
	
	/*public FbpboxmagO moveInQueryFnc(FbpboxmagI inTrx) {
		FbpboxmagO outTrx = new FbpboxmagO();
		outTrx.setTrx_id(TX_NAME);
		outTrx.setType_id(TRX_OUT);
		
		String tool_id = inTrx.getTool_id_fk();
		String box_id = inTrx.getBox_id();
		String hql = "FROM Ret_box where 1=1 ";
		if (box_id != null) {
			hql = hql + " and id.box_id ='" + box_id + "'";
		}else if(tool_id != null){
			hql += "and tool_id_fk ='"+tool_id+"'";
		}
		List<Ret_box> retBoxList = retBoxDao.find(hql);

		if (retBoxList.isEmpty()) {
			outTrx.setRtn_code(E_RET_BOX + E_READ_NOT_FOUND + "");
			outTrx.setRtn_mesg("未找到箱号信息！");
			return outTrx;
		}
		List<FbpboxmagOA> oaryList = new ArrayList<FbpboxmagOA>();
		for (Ret_box retBox : retBoxList) {
			FbpboxmagOA oary = new FbpboxmagOA();
			oary.setBox_id(retBox.getBox_id());
			oary.setBox_stat(retBox.getBox_stat());
			oary.setPrd_qty(retBox.getPrd_qty());
			oary.setTool_id_fk(retBox.getTool_id_fk());
			oary.setWo_id_fk(retBox.getWo_id_fk());
			oary.setMdl_id_fk(retBox.getMdl_id_fk());
			oary.setCus_no(retBox.getCus_no());
			oaryList.add(oary);
		}
		outTrx.setOary(oaryList);
		outTrx.setTbl_cnt(oaryList.size());
		outTrx.setRtn_code(RETURN_CODE_OK);
		outTrx.setRtn_mesg(RETURN_MESG_OK);
		return outTrx;
	}*/

	public FbpboxmagO deleteFnc(FbpboxmagI inTrx) {
		FbpboxmagO outTrx = new FbpboxmagO();
		StringBuffer box_sb = new StringBuffer();
		outTrx.setTrx_id(TX_NAME);
		outTrx.setType_id(TRX_OUT);
		for(FbpboxmagIA iary:inTrx.getIary()){
			//检查箱子是否被使用
			Ret_box ret_box = retBoxDao.get(iary.getBox_id());
			if(ret_box == null){
				outTrx.setRtn_code(E_RET_BOX + E_READ_NOT_FOUND + "");
				outTrx.setRtn_mesg("箱子[" + iary.getBox_id() + "]不存在！！！");
				return outTrx;
			}
			if(!ret_box.getBox_stat().trim().equals(PROC_EMPTY)){
				outTrx.setRtn_code(E_FBPBOXMAG_IN_USED + "");
				outTrx.setRtn_mesg("箱子[" + iary.getBox_id() + "]状态["+ret_box.getBox_stat().trim()+"不为空，不可以删除！");
				return outTrx;
			}
			//check real_empt TODO:
			
//			List<Ret_prd_info> prdInfoList = new ArrayList<Ret_prd_info>();
//			String prd_hql = "FROM Ret_prd_info where box_id_fk ='" + iary.getBox_id() + "'";
//			prdInfoList = retPrdInfoDao.find(prd_hql);
//			if(!prdInfoList.isEmpty()) {
//				outTrx.setRtn_code(E_FBPBOXMAG_IN_USED + "");
//				outTrx.setRtn_mesg("箱子[" + iary.getBox_id() + "]已经被使用，无法删除！！！");
//				return outTrx;
//			}
			
			retBoxDao.delete(ret_box);
		}
		outTrx.setRtn_code(RETURN_CODE_OK);
		outTrx.setRtn_mesg(RETURN_MESG_OK);
		return outTrx;
	}

	public FbpboxmagO errActionFnc() {
		FbpboxmagO outTrx = new FbpboxmagO();
		outTrx.setTrx_id(TX_NAME);
		outTrx.setType_id(TRX_OUT);
		outTrx.setRtn_code("0000009");
		outTrx.setRtn_mesg("Invalid Action_flg");
		return outTrx;
	}

}
